/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package EstrategiasCapturaTrama;

import Alertas.FabricaDeAlerta;
import Entidades.*;
import Persistencia.FachadaPersistencia;
import java.util.ArrayList;

/**
 *
 * @author Luis
 */
public class EstrategiaTramaConNumeral implements EstrategiaTrama {

    @Override
    /**
     * Recibe una trama y la persiste sus mediciones teniendo en cuenta la
     * posicion de cada Medicion su respectivo Sensor
     */
    public void materializarTrama(String trama) {

        if (trama.startsWith("#")) {
            char datos[] = new char[trama.length() + 1];
            trama.getChars(1, (trama.length()), datos, 1); // obtengo cada caracter de la trama excepto el #
            datos[datos.length - 1] = ','; // agrego la "," para poder obtener la ultima medicion
            String numero = "";
            ArrayList todo = new ArrayList();
            for (int i = 1; i < datos.length; i++) {
                if ((datos[i] != ',')) {  // si el caracter no es una coma
                    numero += datos[i];
                } else {
                    todo.add(numero);
                    numero = "";
                }
            }
            ArrayList mediciones = new ArrayList();
            int codigoEquipo = Integer.parseInt((String) todo.get(0));
            String cantidadSensores = (String) todo.get(1);
            todo.remove(0); // elimino el numero del equipo
            todo.remove(0); // elimino el numero de sensores
            if (Integer.parseInt(cantidadSensores) == todo.size()) {  // si las cantidad de mediciones son iguales a la cantidad de sensores
                mediciones = todo;
            } else {
                if (Integer.parseInt(cantidadSensores) < todo.size()) { // si la cantidad de sensores es menor a las mediciones tomadas
                    for (int i = 0; i < Integer.parseInt(cantidadSensores); i++) {
                        mediciones.add(todo.get(i));
                    }
                } else { // la cantidad de sensores es mayor a las mediciones tomadas
                    for (int i = 0; i < todo.size(); i++) {
                        mediciones.add(todo.get(i));
                    }
                }
            }
            Equipo equipo;
            System.out.println("codigo de equipo:" + codigoEquipo);
            equipo = (Equipo) FachadaPersistencia.getInstancia().buscarEquipo(codigoEquipo);
            if (equipo != null) {
                ArrayList<Sensor> sensores = equipo.getSensores();
                ArrayList<Sensor> sensoresAlertar = new ArrayList<>();
                ArrayList<Medicion> medicionesAlertar = new ArrayList<>();
                for (int i = 1; i <= Integer.parseInt(cantidadSensores); i++) {
                    Sensor sen = buscarSensor(i, sensores);
                    if ((sen != null) && !((mediciones.get(i - 1)).equals(sen.getSdSensorModelosensor().getValorError()))) { // si viene con error no la guardo
                        Medicion medicion = new Medicion();
                        medicion.setIdSensor(sen.getIdSensor());
                        medicion.setCorrecto(validarMedicion(Float.parseFloat((String) mediciones.get(i - 1)), sen));
                        medicion.setValor(Float.parseFloat((String) mediciones.get(i - 1)));
                        FachadaPersistencia.getInstancia().guardar(medicion);
                        if (sen.getSdSensorEstadosensor().getDescripcion().equals("Activo") && verificarFuncionamiento(sen)) {
                            sensoresAlertar.add(sen);
                            medicionesAlertar.add(medicion);
                        }
                    }
                }
                if (!sensoresAlertar.isEmpty()) {
                    enviarAlerta(sensoresAlertar, medicionesAlertar);
                }
            }
        }
    }

    /**
     * Busca el Sensor que tiene la posición de la medición a persistir
     *
     * @param posicion numero de posición que tiene la medición en la trama
     * recibida
     * @param sensores ArrayList de los sensores no eliminados del Equipo que
     * envió la trama
     * @return
     */
    public Sensor buscarSensor(int posicion, ArrayList<Sensor> sensores) {

        for (int i = 0; i < sensores.size(); i++) {
            if (posicion == sensores.get(i).getPosicion()) {
                return sensores.get(i);
            }
        }
        return null;
    }

    public boolean validarMedicion(float _medicion, Sensor _sensor) {

        Valoresconfigurados valores = _sensor.getValoresConfigurados();
        if (_medicion >= valores.getValorMinimo() && _medicion <= valores.getValorMaximo()) {
            return true;
        } else {
            return false;
        }
    }

    public boolean verificarFuncionamiento(Sensor _sensor) {

        ArrayList<Medicion> mediciones = FachadaPersistencia.getInstancia().buscarMediciones(_sensor.getIdSensor().toString(), _sensor.getTiempoFueraDeLosLimites());
        if (mediciones.isEmpty()) {
            return false;
        }
        for (int i = 0; i < mediciones.size(); i++) {
            if (mediciones.get(i).getCorrecto() == true) {
                return false;
            }
        }
        return true;
    }

    public void enviarAlerta(ArrayList<Sensor> _sensores, ArrayList<Medicion> _mediciones) {
        FabricaDeAlerta.getInstancia().getAlerta("FueraDeLoNormal").enviarAlerta(_sensores, _mediciones);
    }
}
